﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace OBUActivation
{
    /// <summary>
    /// 智能卡 IO 端口通信规约
    /// </summary>
    internal struct SCARD_IO_REQUEST
    {
        /// <summary>
        /// 协议类型
        /// </summary>
        public int m_Ptl;

        /// <summary>
        /// 数据位长度
        /// </summary>
        public int m_PcL;
    }

    /// <summary>
    /// SC 卡驱动封装类
    /// </summary>
    class SCDriver
    {
        /// <summary>
        /// 初始化读卡器环境
        /// </summary>
        [DllImport("Winscard.dll")]
        public static extern Int32 SCardEstablishContext(UInt32 scope, int lhs, int rhs, out int pcscContext);

        /// <summary>
        /// 列举与之连接的读卡器
        /// </summary>
        [DllImport("winscard.dll")]
        private static extern Int32 SCardListReaders(int hContext, byte[] mszGroups, byte[] mszReaders, ref int pcchReaders);


        /// <summary>
        /// 返回机器上的读卡器列表
        /// </summary>
        public static List<string> SCardListReaders(int hContext)
        {
            List<string> list = new List<string>();
            // 获取读卡器名称列表的字节数
            int count = 0;
            int result = SCardListReaders(hContext, null, null, ref count);
            if (result != 0)
            {
                return null;
            }
            // 获取读卡器名称列表
            byte[] reads = new byte[count];
            result = SCardListReaders(hContext, null, reads, ref count);
            if (result != 0)
            {
                return null;
            }
            // 获取读卡器列表字符串
            ASCIIEncoding encoding = new ASCIIEncoding();
            string strBuffer = encoding.GetString(reads);
            // 分割列表
            int index = 0;
            while (strBuffer[0] != '\0')
            {
                // 添加一个读卡器名称
                index = strBuffer.IndexOf('\0');
                string reader = strBuffer.Substring(0, index);
                list.Add(reader);
                // 处理剩余名称列表
                count = count - (reader.Length + 1);
                strBuffer = strBuffer.Substring(index + 1, count);
            }
            return list;
        }

        /// <summary>
        /// 与智能卡连接
        /// </summary>
        [DllImport("winscard.dll", CharSet = CharSet.Auto)]
        public static extern int SCardConnect(int hContext, string szReader, int dwShareMode, int dwPreferredProtocols, ref int phCard, ref int pdwActiveProtocol);

        /// <summary>
        /// 向卡片发送数据并期待返回内容
        /// </summary>
        [DllImport("winscard.dll")]
        public static extern int SCardTransmit(int hCard, ref SCARD_IO_REQUEST pioSendPci, byte[] pbSendBuffer, int cbSendLength, ref SCARD_IO_REQUEST pioRecvPci, ref byte pbRecvBuffer, ref int pcbRecvLength);

        /// <summary>
        /// 释放连接
        /// </summary>
        [DllImport("winscard.dll")]
        public static extern int SCardDisconnect(int hCard, int dwDisposition);

        /// <summary>
        /// 释放资源
        /// </summary>
        [DllImport("winscard.dll")]
        public static extern int SCardReleaseContext(int hContext);

        /// <summary>
        /// 返回读卡器状态
        /// </summary>
        [DllImport("winscard.dll")]
        public static extern int SCardStatus(int hCard, byte[] szReaderName, out int pcchReaderLen, out int pdwState, out int pdwProtocol, byte[] pbAtr, out int pcbAtrLen);
    }
}
